package com.liuceng.zen.web.controller;

import com.liuceng.zen.constants.Constants;
import com.liuceng.zen.pojo.domain.*;
import com.liuceng.zen.pojo.form.CampaignForm;
import com.liuceng.zen.pojo.form.ForntCampaignForm;
import com.liuceng.zen.service.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.amqp.core.AmqpTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.text.SimpleDateFormat;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@RequestMapping(value = "/campaigns")
@Controller
public class CampaignController extends BaseController {
  private final static Logger LOG = LoggerFactory.getLogger(CampaignController.class);

  private final static Short OWNED_OPERATION = 2;
  @Autowired
  GdtRptCampaignDailyService gdtRptCampaignDaily;
  @Autowired
  RptMemberCampaignGdtMobileDailyService campaignGdtMobileDaily;
  @Autowired
  RptMemberCampaignGdtPcDailyService campaignGdtPcDaily;
  @Autowired
  GdtAdGroupService gdtAdGroupService;
  @Autowired
  GdtCampaignService gdtCampaignService;
  @Autowired
  RptFrontCampaignService rptFrontCampaignService;
  @Autowired
  RptFrontAdGroupService frontAdGroupService;
  @Autowired
  MemberService memberService;
  @Autowired
  DictRegionService dictRegionService;
  @Autowired
  FrontCampaignService frontCampaignService;
  @Autowired
  FrontAdGroupService frontAdGroupServices;
  @Autowired
  MemberDepartmentRelKeyService memberDepartmentRelKeyService;
  @Autowired
  MessageService messageService;
  @Autowired
  DashboardService dashboardService;
  @Autowired
  NewRptFrontCampaignDailyService newRptFrontCampaignDailyService;
  @Autowired
  private DepartmentService departmentService;
  @Autowired
  private AdminService adminService;
  @Autowired
  private MemberOperationNotificationService memberOperationNotificationService;
  @Autowired
  private SmsSenderService smsSenderService;
  @Autowired
  private OperatingTrackService operatingTrackService;
  @Autowired
  private AmqpTemplate adLifeTemplate;

  @Value("${hailiangtong.url}")
  private String hailiangtong;

  // 广告和计划---广告计划---广告计划列表
  @RequestMapping(value = "", method = RequestMethod.GET)
  public String index(@ModelAttribute("form") CampaignForm form) {
    // 获取登录客户的信息
    Member member = memberService.find(getCurrentUserId());
    // 获取客户所在城市
    member.setCityStr(dictRegionService.find(member.getCity()).getName());
    // pc
    RptFrontCampaign pcCampaign = new RptFrontCampaign();
    pcCampaign.setStatus(RptFrontCampaign.STATUS_RUN);
    // 计划名
    pcCampaign.setCname(member.getCityStr() + member.getCompanyName() + "PC");
    // 开始时间
    pcCampaign.setStartAt(member.getCreatedAt());
    // PC端的总花费
    BigDecimal pcCost = rptFrontCampaignService.findPcCost(getCurrentUserId());
    pcCampaign.setCost(pcCost);
    // PC端曝光量和点击量
    int pcPv = rptFrontCampaignService.findPcPv(getCurrentUserId());
    // 点击数
    int pcPc = rptFrontCampaignService.findPcPc(getCurrentUserId());
    pcCampaign.setPv(pcPv);
    pcCampaign.setPc(pcPc);
    pcCampaign.setSitesetType(Constants.SITESET_TYPE_PC);
    // 点击率
    pcCampaign.setCtr(pcPv == 0 ? new BigDecimal(0) : new BigDecimal(pcPc * 100.0 / pcPv));
    // 点击均价
    pcCampaign.setCostPerClick(pcPc == 0 ? new BigDecimal(0) : pcCost.divide(new BigDecimal(pcPc),
        3, RoundingMode.UP));
    // 千次曝光成本
    pcCampaign.setCostPerView(pcPv == 0 ? new BigDecimal(0) : pcCost.divide(new BigDecimal(pcPv),
        3, RoundingMode.UP).multiply(new BigDecimal(1000)));

    // mob
    RptFrontCampaign mobileCampaign = new RptFrontCampaign();
    mobileCampaign.setStatus(RptFrontCampaign.STATUS_RUN);
    // 计划名
    mobileCampaign.setCname(member.getCityStr() + member.getCompanyName() + "Mob");
    // 开始时间
    mobileCampaign.setStartAt(member.getCreatedAt());
    // 移动端的总花费
    BigDecimal mobileCost = rptFrontCampaignService.findMobileCost(getCurrentUserId());
    mobileCampaign.setCost(mobileCost);
    // 移动端曝光量和点击量
    int mobilePv = rptFrontCampaignService.findMobilePv(getCurrentUserId());
    int mobilePc = rptFrontCampaignService.findMobilePc(getCurrentUserId());
    mobileCampaign.setPv(mobilePv);
    mobileCampaign.setPc(mobilePc);
    mobileCampaign.setSitesetType(Constants.SITESET_TYPE_MOBILE);
    // 点击率
    mobileCampaign.setCtr(mobilePv == 0 ? new BigDecimal(0) : new BigDecimal(mobilePc * 100.0
        / mobilePv));
    // 点击成本
    mobileCampaign.setCostPerClick(mobilePc == 0 ? new BigDecimal(0) : mobileCost.divide(
        new BigDecimal(mobilePc), 3, RoundingMode.UP));
    // 千次曝光成本
    mobileCampaign.setCostPerView(mobilePv == 0 ? new BigDecimal(0) : mobileCost.divide(
        new BigDecimal(mobilePv), 3, RoundingMode.UP).multiply(new BigDecimal(1000)));
    // /
    form.setCampaigns(Arrays.asList(pcCampaign, mobileCampaign));
    return "campaign/index";
  }

  /**
   * 广告计划详细情况
   * 
   * @param form
   * @param id
   * @return
   */
  @RequestMapping(value = "/sitetype/{id}", method = RequestMethod.GET)
  public String campaignDetail(@ModelAttribute("form") CampaignForm form, @PathVariable Integer id) {
    form.setFrontCampaign(frontCampaignService.find(id));
    // 已经创建的广告数量
    form.setAdCount(frontAdGroupServices.selectAdGroupCount(getCurrentUserId()));
    // 获取建议出价信息
    if(1==form.getSitesetType()){
      form.setOfferMessage(frontAdGroupServices.getPcOfferMessage());
    }else{
      form.setOfferMessage(frontAdGroupServices.getMobileOfferMessage());
    }
    return "campaign/detail";
  }

  @RequestMapping(value = "/list", method = RequestMethod.GET)
  public String list(@ModelAttribute("form") ForntCampaignForm form) {
    Map<String, Object> map = new HashMap<>();
    map.put("memberId", getCurrentUserId());
    List<FrontCampaign> list = frontCampaignService.search(map);
    if (list != null && list.size() != 0 && list.get(0) != null) {
      for (FrontCampaign one : list) {
        map.put("frontCampaignId", one.getId());
        map.put("auditType", BaseDomain.AUDIT_PASS);
        Map<String, Object> newRptFront = newRptFrontCampaignDailyService.findTotalRptData(map);
        one.setRptData(newRptFront);
      }
    } else {
      LOG.error("没有广告计划 memberId=" + getCurrentUserId());
      return ERROR_VIEW;
    }
    form.setFrontCampaigns(list);
    // 已经创建的广告数量
    form.setAdCount(frontAdGroupServices.selectAdGroupCount(getCurrentUserId()));
    return "campaign/list";
  }

  // 广告计划的开启和关闭
  @RequestMapping(value = "/{id}/{status}", method = RequestMethod.POST)
  public @ResponseBody String editStatus(@PathVariable Integer status, @PathVariable Integer id,
      @ModelAttribute("form") ForntCampaignForm form) {
    FrontCampaign frontCampaign = frontCampaignService.find(id);
    frontCampaign.setUpdatedId(getCurrentUserId());
    frontCampaign.setCampaignStatus(status == ForntCampaignForm.START ? ForntCampaignForm.STOP
        : ForntCampaignForm.START);
    frontCampaignService.update(frontCampaign);

    // 自营修改广告有短信提醒，代运营修改广告不需要短信提醒
    Short operationType = getUserContext().getMember().getOperationType();
    if (OWNED_OPERATION == operationType) {
      // 添加广告计划开启或关闭操作轨迹
      if (status == ForntCampaignForm.START) {
        operatingTrackService.addOperatingTrack(getUserContext().getMember(),
            frontCampaign.getName(), "暂停广告", null, null, null, frontCampaign.getId());
      } else {
        operatingTrackService.addOperatingTrack(getUserContext().getMember(),
            frontCampaign.getName(), "开启广告", null, null, null, frontCampaign.getId());
      }
      //管理计划下广告生命时长
      frontCampaignService.processAdGroupPutLife(frontCampaign);
      // 获取媒介
      Map<String, Object> map = new HashMap<>();
      map.put("memberId", getCurrentUserId());
      map.put("mediumType", frontCampaign.getCampaignType());

      List<MemberDepartmentRelKey> memberDepartmentRelKeys =
          memberDepartmentRelKeyService.findByParams(map);
      SimpleDateFormat simple = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
      if (memberDepartmentRelKeys != null && memberDepartmentRelKeys.size() > 0) {
        for (int i = 0; i < memberDepartmentRelKeys.size(); i++) {
          MemberOperationNotification memberOperationNotification =
              new MemberOperationNotification();
          Member member = getUserContext().getMember();

          memberOperationNotification.setMemberId(member.getId());
          memberOperationNotification.setCampaignId(id);
          memberOperationNotification.setDataFlag(MemberOperationNotification.UNTREATED);
          memberOperationNotification.setCompanyName(member.getCompanyName());
          if (status == ForntCampaignForm.START) {
            memberOperationNotification.setAction(MemberOperationNotification.STOP);
          } else {
            memberOperationNotification.setAction(MemberOperationNotification.START);
          }
          Admin admin = adminService.find(memberDepartmentRelKeys.get(i).getAdminId());
          memberOperationNotification.setAdminId(admin.getId());
          memberOperationNotification.setAdminName(admin.getName());
          memberOperationNotification.setDepartmentId(admin.getDepartmentId());
          Department department = departmentService.find(admin.getDepartmentId());
          memberOperationNotification.setDepartmentName(department.getName());

          memberOperationNotificationService.insert(memberOperationNotification);
          // 旧版短信平台
          // String content = messageService.doMessage(member.getCompanyName(),
          // simple.format(frontCampaign.getUpdatedAt()), memberOperationNotification.getAction(),
          // frontCampaign.getName(), admin, memberOperationNotification.getId());
          // 新版短信平台
          String content =
              "客户" + member.getCompanyName() + "于" + simple.format(frontCampaign.getUpdatedAt())
                  + "对广告：" + frontCampaign.getName() + "进行了"
                  + memberOperationNotification.getAction() + "操作，请及时处理。收到信息请点击下面的链接进行确认："
                  + hailiangtong + "/member_operation_notification/edit/"
                  + memberOperationNotification.getId() + "【海量通】";
          smsSenderService.sender(admin.getPhone(), content);
          memberOperationNotification.setContent(content);
          logger.info(content);// 打印短信日志
          memberOperationNotificationService.update(memberOperationNotification);
          messageService.timerTaskCampaign(memberOperationNotification, admin, member,
              frontCampaign);
        }
      } else {
        MemberOperationNotification memberOperationNotification = new MemberOperationNotification();
        Member member = getUserContext().getMember();

        memberOperationNotification.setMemberId(member.getId());
        memberOperationNotification.setCampaignId(id);
        memberOperationNotification.setDataFlag(MemberOperationNotification.UNTREATED);
        memberOperationNotification.setCompanyName(member.getCompanyName());
        if (status == ForntCampaignForm.START) {
          memberOperationNotification.setAction(MemberOperationNotification.STOP);
        } else {
          memberOperationNotification.setAction(MemberOperationNotification.START);
        }
        Admin admin = adminService.find(member.getAdminId());
        memberOperationNotification.setAdminId(admin.getId());
        memberOperationNotification.setAdminName(admin.getName());
        memberOperationNotification.setDepartmentId(admin.getDepartmentId());
        Department department = departmentService.find(admin.getDepartmentId());
        memberOperationNotification.setDepartmentName(department.getName());

        memberOperationNotificationService.insert(memberOperationNotification);
        // 旧版短信平台
        // String content = messageService.doMessage(member.getCompanyName(),
        // simple.format(frontCampaign.getUpdatedAt()), memberOperationNotification.getAction(),
        // frontCampaign.getName(), admin, memberOperationNotification.getId());
        // 新版短信平台
        String content =
            "客户" + member.getCompanyName() + "于" + simple.format(frontCampaign.getUpdatedAt())
                + "对广告：" + frontCampaign.getName() + "进行了"
                + memberOperationNotification.getAction() + "操作，请及时处理。收到信息请点击下面的链接进行确认："
                + hailiangtong + "/member_operation_notification/edit/"
                + memberOperationNotification.getId() + "【海量通】";
        smsSenderService.sender(admin.getPhone(), content);
        logger.info(content);// 打印短信日志
        memberOperationNotification.setContent(content);
        memberOperationNotificationService.update(memberOperationNotification);
        messageService.timerTaskCampaign(memberOperationNotification, admin, member, frontCampaign);
      }
    }
    if (status == 1) {
      return "关闭";
    } else {
      return "开启";
    }
  }

  /**
   * 修改日预算
   * 
   * @param id
   * @param form
   * @return
   */
  @RequestMapping(value = "/edit/day_budget/{id}", method = RequestMethod.POST)
  public @ResponseBody String editDayBudget(@PathVariable Integer id,
      @ModelAttribute("form") ForntCampaignForm form) {
    FrontCampaign frontCampaign = frontCampaignService.find(id);
    frontCampaign.setDayBudget(form.getDayBudget());
    frontCampaign.setUpdatedId(getCurrentUserId());
    frontCampaignService.update(frontCampaign);
    return "";
  }

  /**
   * 修改广告出价
   * 
   * @param id
   * @param form
   * @return
   */
  @RequestMapping(value = "/edit/ad_offer/{id}", method = RequestMethod.POST)
  public @ResponseBody String editAdOffer(@PathVariable Integer id,
      @ModelAttribute("form") ForntCampaignForm form) {
    FrontCampaign frontCampaign = frontCampaignService.find(id);
    frontCampaign.setAdOffer(form.getAdOffer());
    frontCampaign.setUpdatedId(getCurrentUserId());
    frontCampaignService.update(frontCampaign);
    return "";
  }

  /**
   * 同时修改日预算和出价
   * 
   * @param type
   * @param form
   * @return
   */
  @RequestMapping(value = "/edit/ad_offer/and/day_budget/{type}", method = RequestMethod.POST)
  public @ResponseBody String editAdOfferAndDayBudget(@PathVariable Integer type,
      @ModelAttribute("form") ForntCampaignForm form) {
    Map<String, Object> map = new HashMap<>();
    map.put("memberId", getCurrentUserId());
    map.put("campaignType", type);
    FrontCampaign frontCampaign = frontCampaignService.findOneByParams(map);
    frontCampaign.setAdOffer(form.getAdOffer());
    frontCampaign.setDayBudget(form.getDayBudget());
    frontCampaign.setUpdatedId(getCurrentUserId());
    frontCampaignService.update(frontCampaign);
    return "";
  }

}
